#pragma once
#include <boost/typeof/typeof.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/web/server/api/ApiController.hpp"
#include "oatpp/web/mime/multipart/Multipart.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include "../vo/ConfigVo.h"
#include "../dto/SimpleDto.h"
#include "../dto/ConfigListDto.h"
#include "../service/ConfigService.h"
#include "../common/Common.h"
#include "../config/SystemConfig.h"

#include OATPP_CODEGEN_BEGIN(ApiController)

/**
 * 配置管理控制器
 */
class ConfigController : public oatpp::web::server::api::ApiController {
public:
	ConfigController(const std::shared_ptr<ObjectMapper>& objectMapper)
		: oatpp::web::server::api::ApiController(objectMapper)
	{}

	/**
	 * 保存配置
	 */
	ENDPOINT("POST", "/config/save", saveConfig,
		HEADER(String, authorization, "Authorization"),
		REQUEST(std::shared_ptr<IncomingRequest>, request)) {

		// 返回操作结果
		auto result = ConfigListDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		// 查找用户信息
		if (SystemConfig::get_mutable_instance().GetBoxConf().GetUser().GetToken() !=
			TextUtil::get_mutable_instance().GetToken(authorization.getValue("")))
		{
			result->description = "无效令牌!";
			return createDtoResponse(Status::CODE_200, result);
		}

		oatpp::String content = request->readBodyToString();
		std::string str = content.getValue("");

		std::stringstream iss;
		iss.str(str);

		boost::property_tree::ptree tree_root;
		boost::property_tree::json_parser::read_json(iss, tree_root);

		std::vector<ConfigInfo> configs;
		for (BOOST_AUTO(pos, tree_root.begin()); pos != tree_root.end(); ++pos)
		{
			std::string key = pos->second.get<std::string>("key", "");
			std::string params = pos->second.get<std::string>("params", "");
			int enabled = pos->second.get<int>("enabled", 1);

			ConfigInfo item;
			item.SetKey(key);
			item.SetEanble(enabled);
			item.SetParams(params);
			configs.push_back(item);
		}

		ConfigService configService;
		for (size_t index = 0; index < configs.size(); ++index)
		{
			// 当前配置项
			ConfigInfo& item = configs[index];
			if (item.GetKey() == CONFIG_TYPE_ID)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetId(item.GetParams());
				SystemConfig::get_mutable_instance().GetLocalConf().SetId(item.GetParams());
				SystemConfig::get_mutable_instance().SaveConfig();
			}
			else if (item.GetKey() == CONFIG_TYPE_SAVE_DAYS)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetSaveDays(std::stoi(item.GetParams()));
			}
			else if (item.GetKey() == CONFIG_TYPE_PATROL_NUM)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetPatrolNum(std::stoi(item.GetParams()));
			}
			else if (item.GetKey() == CONFIG_TYPE_SHOW_LABEL)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetShowLabel(std::stoi(item.GetParams()) == 1);
			}
			else if (item.GetKey() == CONFIG_TYPE_ALARM_RECORD)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetAlarmRecord(std::stoi(item.GetParams()) == 1);
			}
			else if (item.GetKey() == CONFIG_TYPE_AUTO_RESTART)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetAutoRestart(std::stoi(item.GetParams()) == 1);
			}
			else if (item.GetKey() == CONFIG_TYPE_ALARM_URL)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetAlarmUrl(item.GetParams());
			}
			else if (item.GetKey() == CONFIG_TYPE_SOCKET_URL)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetSocketUrl(item.GetParams());
			}
			configService.UpdateByKey(item);
		}

		// 返回操作结果
		result->error = 0;
		result->description = "success";
		return createDtoResponse(Status::CODE_200, result);
	}

	/**
	 * 保存配置
	 */
	ENDPOINT("POST", "/config/save2", saveConfig2,
		HEADER(String, authorization, "Authorization"),
		BODY_DTO(oatpp::List<oatpp::Object<ConfigVo>>, lst)) {

		// 返回操作结果
		auto result = ConfigListDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		// 查找用户信息
		if (SystemConfig::get_mutable_instance().GetBoxConf().GetUser().GetToken() !=
			TextUtil::get_mutable_instance().GetToken(authorization.getValue("")))
		{
			result->description = "无效令牌!";
			return createDtoResponse(Status::CODE_200, result);
		}
	
		// 保存所有配置
		ConfigService configService;
		for (size_t index = 0; index < lst->size(); ++index)
		{
			// 当前配置项
			oatpp::Object<ConfigVo>& item = lst[index];
			if (item->key.getValue("") == CONFIG_TYPE_ID)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetId(item->params.getValue(""));
				SystemConfig::get_mutable_instance().GetLocalConf().SetId(item->params.getValue(""));
				SystemConfig::get_mutable_instance().SaveConfig();
			}
			else if (item->key.getValue("") == CONFIG_TYPE_SAVE_DAYS)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetSaveDays(std::stoi(item->params.getValue("1")));
			}
			else if (item->key.getValue("") == CONFIG_TYPE_PATROL_NUM)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetPatrolNum(std::stoi(item->params.getValue("8")));
			}
			else if (item->key.getValue("") == CONFIG_TYPE_SHOW_LABEL)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetShowLabel(std::stoi(item->params.getValue("1")) == 1);
			}
			else if (item->key.getValue("") == CONFIG_TYPE_ALARM_RECORD)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetAlarmRecord(std::stoi(item->params.getValue("1")) == 1);
			}
			else if (item->key.getValue("") == CONFIG_TYPE_AUTO_RESTART)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetAutoRestart(std::stoi(item->params.getValue("1")) == 1);
			}
			else if (item->key.getValue("") == CONFIG_TYPE_ALARM_URL)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetAlarmUrl(item->params.getValue(""));
			}
			else if (item->key.getValue("") == CONFIG_TYPE_SOCKET_URL)
			{
				SystemConfig::get_mutable_instance().GetBoxConf().SetSocketUrl(item->params.getValue(""));
			}

			ConfigInfo config;
			config.SetId(item->id.getValue(""));
			config.SetEanble(item->enable.getValue(1));
			config.SetCreateTime(DateTime::FromString(item->createTime));
			config.SetKey(item->key.getValue(""));
			config.SetParams(item->params.getValue(""));
			configService.Update(config);
		}

		// 返回操作结果
		result->error = 0;
		result->description = "success";
		return createDtoResponse(Status::CODE_200, result);
	}

	/**
	 * 查询配置
	 */
	ENDPOINT("GET", "/config/list", listConfig,
		HEADER(String, authorization, "Authorization")) {

		// 返回操作结果
		auto result = ConfigListDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		// 查找用户信息
		if (SystemConfig::get_mutable_instance().GetBoxConf().GetUser().GetToken() !=
			TextUtil::get_mutable_instance().GetToken(authorization.getValue("")))
		{
			result->description = "无效令牌!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 查找用户信息
		if (SystemConfig::get_mutable_instance().GetBoxConf().GetUser().GetToken() !=
			TextUtil::get_mutable_instance().GetToken(authorization.getValue("")))
		{
			result->description = "无效令牌!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 查询配置信息
		std::vector<ConfigInfo> configs;
		ConfigService configService;
		configService.FindPage(0, 100, configs);

		// 初始化空列表
		oatpp::List<oatpp::Object<ConfigVo>> items({});

		// 填充配置列表
		for (size_t index = 0; index < configs.size(); ++index)
		{
			auto config = ConfigVo::createShared();
			config->id = configs[index].GetId();
			config->key = configs[index].GetKey();
			config->params = configs[index].GetParams();
			config->enable = configs[index].GetEanble();
			config->createTime = configs[index].GetCreateTime().ToNormalString();
			items->emplace(items->end(), config);
		}

		// 返回配置列表
		result->error = 0;
		result->description = "success";
		result->value = items;
		return createDtoResponse(Status::CODE_200, result);
	}
};

#include OATPP_CODEGEN_END(ApiController)